/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tenant.annotation.TenantIgnore;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.ObjectUtil;
import org.springblade.modules.admin.dto.PlanLogDTO;
import org.springblade.modules.admin.dto.openapi.HtDaySearchCondition;
import org.springblade.modules.admin.entity.MaintainPlanContent;
import org.springblade.modules.admin.entity.MaintainPlanUserDayCount;
import org.springblade.modules.admin.entity.MaintainSign;
import org.springblade.modules.admin.enums.MaintainPlanContentEnum;
import org.springblade.modules.admin.enums.SignEnum;
import org.springblade.modules.admin.enums.TaskStatusEnum;
import org.springblade.modules.admin.enums.WorkTrackStatusEnum;
import org.springblade.modules.admin.mapper.MaintainSignMapper;
import org.springblade.modules.admin.service.IMaintainPlanContentService;
import org.springblade.modules.admin.service.IMaintainPlanContentUserService;
import org.springblade.modules.admin.service.IMaintainSignService;
import org.springblade.modules.admin.service.MaintainMalfunctionLogService;
import org.springblade.modules.admin.vo.MaintainSignVO;
import org.springblade.modules.admin.vo.openapi.HtUserPlanVO;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 维保签到明细 服务实现类
 *
 * @author BladeX
 * @since 2021-05-11
 */
@Service
@Slf4j
public class MaintainSignServiceImpl extends BaseServiceImpl<MaintainSignMapper, MaintainSign> implements IMaintainSignService {

	@Resource
	@Lazy
	private IMaintainPlanContentService planContentService;
	@Resource
	private MaintainMalfunctionLogService malfunctionLogService;
	@Resource
	private IUserService userService;
	@Resource
	private IMaintainPlanContentUserService maintainPlanContentUserService;

	@Override
	public IPage<MaintainSignVO> selectMaintainSignPage(IPage<MaintainSignVO> page, MaintainSignVO maintainSign) {
		return page.setRecords(baseMapper.selectMaintainSignPage(page, maintainSign));
	}

	/**
	 * 系统代签 任务提交时 未签退人员自动签退
	 *
	 * @param planId
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void checkUserSignOut(Long planId) {
		MaintainPlanContent planContent = planContentService.getById(planId);
		List<MaintainSign> signList = super.list(Wrappers.<MaintainSign>lambdaQuery().eq(MaintainSign::getPlanId, planId).isNull(MaintainSign::getSignOutTime));
		if (ObjectUtil.isNotEmpty(signList)) {
			signList.forEach(e -> {
				e.setSignOutStatus(1);
				e.setStatus(2);
				e.setSignOutTime(new Date());
				e.setTimeInterval(0L);
				super.updateById(e);
				// 插入任务记录
				User user = userService.getById(e.getUserId());
				PlanLogDTO planLogDTO = new PlanLogDTO();
				planLogDTO.setSignId(e.getId());
				planLogDTO.setExpDesc("系统代签");
				if (planContent.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_BY.getId())) {
					malfunctionLogService.insertWorkLog(e.getPlanId(), WorkTrackStatusEnum.SIGN_OUT.getTypeName(), TaskStatusEnum.BY_PROCESSED.getStatus(), JSONObject.toJSONString(planLogDTO), AuthUtil.getUserId(), user.getRealName());
				} else if (planContent.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())) {
					malfunctionLogService.insertWorkLog(e.getPlanId(), WorkTrackStatusEnum.SIGN_OUT.getTypeName(), TaskStatusEnum.WX_UNDER_WAY.getStatus(), JSONObject.toJSONString(planLogDTO), AuthUtil.getUserId(), user.getRealName());
				} else if (planContent.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_PARTS.getId())) {
					malfunctionLogService.insertWorkLog(e.getPlanId(), WorkTrackStatusEnum.SIGN_OUT.getTypeName(), TaskStatusEnum.PARTS_CHANGE.getStatus(), JSONObject.toJSONString(planLogDTO), AuthUtil.getUserId(), user.getRealName());
				}
				maintainPlanContentUserService.updatePlanUserSignInfo(e.getPlanId(), SignEnum.SIGN_OUT.getId(), e.getUserId(), e.getSignOutStatus());
			});
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void systemSignByNotSignOut(Integer typeStatus) {
		List<MaintainSign> signList = baseMapper.selectAllNotSignOut(typeStatus);
		if (ObjectUtil.isNotEmpty(signList)) {
			signList.forEach(e -> {
				e.setSignOutStatus(1);
				e.setStatus(2);
				e.setSignOutTime(new Date());
				e.setTimeInterval(0L);
				super.updateById(e);
				// 插入任务记录
				PlanLogDTO planLogDTO = new PlanLogDTO();
				planLogDTO.setSignId(e.getId());
				planLogDTO.setExpDesc("系统代签");
				if (typeStatus.equals(MaintainPlanContentEnum.MAINTAIN_BY.getId())) {
					malfunctionLogService.insertWorkLog(e.getPlanId(), WorkTrackStatusEnum.SIGN_OUT.getTypeName(), TaskStatusEnum.BY_PROCESSED.getStatus(), JSONObject.toJSONString(planLogDTO), e.getTenantId());
				} else if (typeStatus.equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())) {
					malfunctionLogService.insertWorkLog(e.getPlanId(), WorkTrackStatusEnum.SIGN_OUT.getTypeName(), TaskStatusEnum.WX_UNDER_WAY.getStatus(), JSONObject.toJSONString(planLogDTO), e.getTenantId());
				} else if (typeStatus.equals(MaintainPlanContentEnum.MAINTAIN_PARTS.getId())) {
					malfunctionLogService.insertWorkLog(e.getPlanId(), WorkTrackStatusEnum.SIGN_OUT.getTypeName(), TaskStatusEnum.PARTS_CHANGE.getStatus(), JSONObject.toJSONString(planLogDTO), e.getTenantId());
				}
				maintainPlanContentUserService.updatePlanUserSignInfo(e.getPlanId(), SignEnum.SIGN_OUT.getId(), e.getUserId(), e.getSignOutStatus());
			});
		}
	}

	@Override
	public MaintainPlanUserDayCount selectUserDaySignCount(List<Long> planIds, List<Long> userIds) {
		return baseMapper.selectUserDaySignCount(planIds, userIds);
	}

	@Override
	public BigDecimal sumPlanWorkTime(Long planId) {
		return baseMapper.sumPlanWorkTime(planId);
	}

	@Override
	public List<MaintainSign> getMaintainSignList(List<Long> planIds) {
		return baseMapper.getMaintainSignList(planIds);
	}

	@Override
	@TenantIgnore
	public List<HtUserPlanVO> getHtUserPlanByTimeCondition(HtDaySearchCondition htDaySearchCondition) {
		// 1. 参数校验
		if (Func.isEmpty(htDaySearchCondition)
			|| Func.isEmpty(htDaySearchCondition.getStartDate())
			|| Func.isEmpty(htDaySearchCondition.getEndDate())
			|| htDaySearchCondition.getEndDate().before(htDaySearchCondition.getStartDate())) {
			log.warn("参数有误{}", JSONObject.toJSONString(htDaySearchCondition));
			return new ArrayList<>();
		}
		// 2. 兼容预留未来租户配置，单独获取银河独立租户id
		String tenantId = "592800";
		// 3. 构造查询时间并查询
		Date startDate = htDaySearchCondition.getStartDate();
		Date endDate = htDaySearchCondition.getEndDate();
		// 若endDate 在 startDate前，则日志输出warn，直接返回空列表
		if (endDate.before(startDate)) {
			log.warn("结束日期早于起始日期");
			return new ArrayList<>();
		}
		// 将 startDate 变为 startDate 当天时间的 00:00:00，使用 Calendar
		Calendar startDateCalendar = Calendar.getInstance();
		startDateCalendar.setTime(startDate);
		startDateCalendar.set(Calendar.HOUR_OF_DAY, 0);
		startDateCalendar.set(Calendar.MINUTE, 0);
		startDateCalendar.set(Calendar.SECOND, 0);
		startDate = startDateCalendar.getTime();
		// 将 endDate 变为 endDate 当天时间的 23:59:59，使用 Calendar
		Calendar endDateCalendar = Calendar.getInstance();
		endDateCalendar.setTime(endDate);
		endDateCalendar.set(Calendar.HOUR_OF_DAY, 23);
		endDateCalendar.set(Calendar.MINUTE, 59);
		endDateCalendar.set(Calendar.SECOND, 59);
		endDate = endDateCalendar.getTime();
		List<HtUserPlanVO> resultList = baseMapper.getHtUserPlanByTimeCondition(startDate, endDate, tenantId);
		if (Func.isEmpty(resultList)) {
			return new ArrayList<>();
		}
		// resultList 进行处理：补充 typeName 和 isDone
		resultList.forEach(r ->{
			if(Integer.valueOf(1).equals(r.getTypeStatus())){
				r.setTypeName("保养");
				r.setIsDone(Integer.valueOf(TaskStatusEnum.BY_SIGN.getStatus()).equals(r.getStatus()));
			}else{
				r.setTypeName("维修");
				r.setIsDone(Integer.valueOf(TaskStatusEnum.WX_SIGN_FINISH.getStatus()).equals(r.getStatus()));
			}
		});
		return resultList;
	}

}

